package asm.dump;

import org.ricks.asm.ClassVisitor;
import org.ricks.asm.MethodVisitor;

import static org.ricks.asm.Opcodes.ACC_ABSTRACT;
import static org.ricks.asm.Opcodes.ACC_NATIVE;

/**
 * @author chenwei
 * @Description:
 * @date 2022/9/1616:47
 */
public class MethodFindInvokeVisitor extends ClassVisitor {

    private int newOpcode;
    private String newOwner;
    private String newMethodName;
    private String newMethodDesc;

    public MethodFindInvokeVisitor(int api, ClassVisitor classVisitor,
                                      int newOpcode, String newOwner, String newMethodName, String newMethodDesc) {
        super(api, classVisitor);

        this.newOpcode = newOpcode;
        this.newOwner = newOwner;
        this.newMethodName = newMethodName;
        this.newMethodDesc = newMethodDesc;
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
        MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
        if (mv != null && !"<init>".equals(name) && !"<clinit>".equals(name)) {
            boolean isAbstractMethod = (access & ACC_ABSTRACT) != 0;
            boolean isNativeMethod = (access & ACC_NATIVE) != 0;
            if (!isAbstractMethod && !isNativeMethod) {
                mv = new MethodReplaceInvokeAdapter(api, mv);
            }
        }
        return mv;
    }

    private class MethodReplaceInvokeAdapter extends MethodVisitor {
        public MethodReplaceInvokeAdapter(int api, MethodVisitor methodVisitor) {
            super(api, methodVisitor);
        }

        @Override
        public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
            super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
        }
    }

}
